#ifndef __THREAD_H__
#define __THREAD_H__

#include <string>
#include <functional>
#include "plat/nonecopyable.h"
#include "semaphore.h"

#define THREAD_DEFAULT_STACK_SIZE (192 * 4)

class Thread : public NoneCopyable
{
public:
    using THREAD_FUNC = std::function<void(void)>;
    
    enum class ThreadPriority
    {   
        Lowest = 0,
        Low,
        Normal,
        High,
        Highest
    };

public:
    explicit Thread();
    explicit Thread(int stackSize, ThreadPriority priority = ThreadPriority::Normal);
    virtual ~Thread();

public:
    void SetStackSize(int size);
    int GetStackSize();
    uint32_t GetStackSizeSpace();
    
    void SetPriority(ThreadPriority priority);
    ThreadPriority GetPriority();
    void SetThreadName(const std::string &name);
    std::string GetThreadName();
    uint32_t GetThreadId();
    void SetFunc(const THREAD_FUNC &func);
    
    bool IsFinished();
    bool IsRunning(); 

    void Start();
    void Start(const THREAD_FUNC &func);
    void Stop();
    bool Wait(uint32_t timeout = -1);
    void Join();

    void RequestInterruption();
    bool IsInterruptionRequested() const;

public:
    static void Sleep(int ms);
    static uint32_t CurrentThreadId();
    static std::string GetThreadName(uint32_t id);
    static uint32_t GetStackSizeSpace(uint32_t id);
    static int GetThreadCount();

    //框架调用
public:
    void PlatExec();

protected:
    virtual void OnRun();

private:
    void CreateOsThread();

private:
    std::string m_threadName = "default";
    int m_stackSize = THREAD_DEFAULT_STACK_SIZE;
    ThreadPriority m_priority = ThreadPriority::Normal;
    
    bool m_isInterruptionRequested = false;
    bool m_isRunning = false; 
    bool m_isterminate = false; //停止后，自动回收线程，不能再使用
    void *m_osThreadHandle = nullptr;

    THREAD_FUNC m_threadFunc = nullptr;
    Semaphore m_sem{0, 1};
};

#endif // __THREAD_H__
